unit ItemsGui;

interface

uses
  InventionCalc, GlobalRecordsAndEnums, Items, ShowInfoGui, EditItemGui, DecryptorsGui, ImportPricesGui,

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, ExtCtrls;

type
  TfrmEditNewItems = class(TForm)
    ListView: TListView;
    btnOK: TButton;
    btnShowInfo: TButton;
    Panel1: TPanel;
    lblName: TLabel;
    lblPrice: TLabel;
    lblManufacture: TLabel;
    lblBPOME: TLabel;
    lblItemName: TLabel;
    edtItemPrice: TEdit;
    chkItemManufacture: TCheckBox;
    edtItemBPOME: TEdit;
    edtNameFilter: TEdit;
    lblBuildCost: TLabel;
    btnBuildCost: TButton;
    btnEditItem: TButton;
    btnNewItem: TButton;
    gbUserSettings: TGroupBox;
    lblFilterName: TLabel;
    gbFilter: TGroupBox;
    chkT1Item: TCheckBox;
    chkT2Item: TCheckBox;
    chkAdvancedMaterial: TCheckBox;
    chkComponent: TCheckBox;
    chkRAM: TCheckBox;
    chkTradegoods: TCheckBox;
    chkDatacore: TCheckBox;
    chkMineral: TCheckBox;
    chkCapComponent: TCheckBox;
    chkCapT2Component: TCheckBox;
    chkSalvage: TCheckBox;
    chkInterface: TCheckBox;
    lblFilterType: TLabel;
    btnAllItemsBuildCost: TButton;
    btnDecryptors: TButton;
    btnImportPrices: TButton;
    btnHelp: TButton;
    btnAllItemsManufacture: TButton;
    btnAllItemsBPOME: TButton;
    GroupBox1: TGroupBox;
    procedure btnOKClick(Sender: TObject);
    procedure ListViewChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure edtItemPriceChange(Sender: TObject);
    procedure chkItemManufactureClick(Sender: TObject);
    procedure edtItemBPOMEChange(Sender: TObject);
    procedure edtNameFilterChange(Sender: TObject);
    procedure btnBuildCostClick(Sender: TObject);
    procedure btnShowInfoClick(Sender: TObject);
    procedure ListViewDblClick(Sender: TObject);
    procedure btnEditItemClick(Sender: TObject);
    procedure btnNewItemClick(Sender: TObject);
    procedure ListViewColumnClick(Sender: TObject; Column: TListColumn);
    procedure ListViewCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    procedure chkT1ItemClick(Sender: TObject);
    procedure chkT2ItemClick(Sender: TObject);
    procedure chkAdvancedMaterialClick(Sender: TObject);
    procedure chkComponentClick(Sender: TObject);
    procedure chkRAMClick(Sender: TObject);
    procedure chkTradegoodsClick(Sender: TObject);
    procedure chkDatacoreClick(Sender: TObject);
    procedure chkMineralClick(Sender: TObject);
    procedure chkCapComponentClick(Sender: TObject);
    procedure chkCapT2ComponentClick(Sender: TObject);
    procedure chkSalvageClick(Sender: TObject);
    procedure chkInterfaceClick(Sender: TObject);
    procedure ListViewCustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure btnAllItemsBuildCostClick(Sender: TObject);
    procedure btnDecryptorsClick(Sender: TObject);
    procedure btnImportPricesClick(Sender: TObject);
    procedure edtItemPriceEnter(Sender: TObject);
    procedure btnHelpClick(Sender: TObject);
    procedure btnAllItemsBPOMEClick(Sender: TObject);
    procedure btnAllItemsManufactureClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    filterstring: String;
    loading: Boolean;
    filter: array [-1..11] of Boolean;
//    sortcolumn: Integer;
//    sortdirection: boolean; // true: a-z, false: z-a
    manufacture: boolean; // boolean which determines what the manufacture property for all items should be set to.

    procedure LoadItems;
    procedure ClearSelection;
    procedure EnableSelection(manufacture: Boolean);
    procedure DisableSelection;
    procedure UpdateTypeFilter(itemtype: EItemType; checked: Boolean);
  public
    constructor Create(AOwner: TComponent; invCalc: TInventionCalc); reintroduce;
  end;

var
  frmEditNewItems: TfrmEditNewItems;
  inventionCalc: TInventionCalc;

implementation

{$R *.dfm}

uses
  StrUtils, Math, ExtActns;

constructor TfrmEditNewItems.Create(AOwner: TComponent; invCalc: TInventionCalc);
var
  i: Integer;
begin
  Inherited Create(AOwner);
  inventionCalc := invCalc;

  filterstring := '';
  for i := 0 to 11 do begin
    filter[i] := inventionCalc.UserSettings.Settings.ItemsFilter[i];
  end;

  chkT1Item.Checked := filter[0];
  chkT2Item.Checked := filter[1];
  chkAdvancedMaterial.Checked := filter[2];
  chkComponent.Checked := filter[3];
  chkRAM.Checked := filter[4];
  chkTradegoods.Checked := filter[5];
  chkDatacore.Checked := filter[6];
  chkMineral.Checked := filter[7];
  chkCapComponent.Checked := filter[8];
  chkCapT2Component.Checked := filter[9];
  chkSalvage.Checked := filter[10];
  chkInterface.Checked := filter[11];

  if (adminhax) then begin
    btnNewItem.Visible := true;
    btnEditItem.Visible := true;
    filter[-1] := true; // IT_Unknown
  end
  else begin
    filter[-1] := false;
  end;

//  sortcolumn := inventionCalc.UserSettings.Settings.ItemsSortColumn;
//  if (sortcolumn < 0) then sortcolumn := 0;
//  sortdirection := inventionCalc.UserSettings.Settings.ItemsSortDirection;

  LoadItems;
end;

procedure TfrmEditNewItems.LoadItems;
var
  i: Integer;
  item: TNewItem;
  listitem: TListItem;
begin
  ListView.Items.Clear;
  loading := true;
  for i := 0 to inventionCalc.GetNewItemCount -1 do begin
    item := TNewItem(inventionCalc.GetItemByIndex(i));
    if ((item <> nil) and (filter[EItemTypeToInteger(item.ItemType)])) then begin
      if ((filterstring = '') or (AnsiContainsText(item.Name, filterstring))) then begin
        listitem := ListView.Items.Add;
        listitem.Data := item;
        listitem.Caption :=  EItemTypeToStringShort(item.ItemType);
        listitem.Subitems.Add(item.Name);
        listitem.SubItems.Add(FloatToStrF(item.Price, ffNumber, 11, 2));
        if (item.CanBeManufactured) then begin
          case item.Manufacture of
            false: listitem.SubItems.Add('No');
            true: listitem.SubItems.Add('Yes');
          end;
          listitem.SubItems.Add(IntToStr(item.BPOME))
        end
        else begin
          listitem.SubItems.Add('-');
          listitem.SubItems.Add('-');
        end;
      end;
    end;
  end;
  manufacture := true;
  loading := false;
  ListView.AlphaSort;
  if (ListView.Items.Count > 0) then begin
    ListView.Selected := ListView.Items[0];
  end
  else begin
    DisableSelection;
  end;
end;

procedure TfrmEditNewItems.ClearSelection;
begin
  ListView.Selected := nil;
  lblItemName.Caption := '';
  edtItemPrice.Text := '';
  btnBuildCost.Caption := '0' + global_ds + '00';
  chkItemManufacture.Checked := false;
  edtItemBPOME.Text := '';
  DisableSelection;
end;

procedure TfrmEditNewItems.EnableSelection(manufacture: Boolean);
begin
  edtItemPrice.Enabled := true;
  btnBuildCost.Enabled := true;
  btnShowInfo.Enabled := true;
  if (manufacture) then begin
    edtItemBPOME.Enabled := true;
    chkItemManufacture.Enabled := true;
  end
  else begin
    edtItemBPOME.Enabled := false;
    chkItemManufacture.Enabled := false;
  end;
end;

procedure TfrmEditNewItems.DisableSelection;
begin
  edtItemPrice.Enabled := false;
  btnBuildCost.Enabled := false;
  chkItemManufacture.Enabled := false;
  edtItemBPOME.Enabled := false;
  btnShowInfo.Enabled := false;
end;

procedure TfrmEditNewItems.btnOKClick(Sender: TObject);
begin
  self.Close;
  self.Release;
end;

procedure TfrmEditNewItems.ListViewChange(Sender: TObject; Item: TListItem;
  Change: TItemChange);
var
  selecteditem: TNewItem;
  CanManufacture: Boolean;
begin
  if (ListView.Selected <> nil) then begin
    selecteditem := TNewItem(Item.Data);
    if ((selecteditem <> nil) and (not loading)) then begin
      CanManufacture := selecteditem.CanBeManufactured;
      EnableSelection(CanManufacture);
      if (CanManufacture) then begin
        chkItemManufacture.Checked := selecteditem.Manufacture;
        edtItemBPOME.Text := IntToStr(selecteditem.BPOME);
      end
      else begin
        chkItemManufacture.Checked := false;
        edtItemBPOME.Text := '';
      end;
      lblItemName.Caption := selecteditem.Name;
      edtItemPrice.Text := FloatToStr(selecteditem.Price);
      btnBuildCost.Caption := FloatToStrF(selecteditem.GetBuildCost(1, selecteditem.BPOME, inventionCalc.UserSettings.Installations.ManufactureMaterialModifier * inventionCalc.UserSettings.Skills.GetProductionEfficiencyModifier), ffNumber, 11, 2);
    end
    else begin
      ClearSelection;
    end;
  end;
end;

procedure TfrmEditNewItems.edtItemPriceChange(Sender: TObject);
var
  price: Double;
  selecteditem: TNewItem;
begin
  if (ListView.Selected <> nil) then begin
    selecteditem := TNewItem(ListView.Selected.Data);
    if ((selecteditem <> nil) and (Length(edtItemPrice.Text) > 0)) then begin
      if (TryStrToFloat(edtItemPrice.Text, price)) then begin
        selecteditem.Price := price;
        ListView.Selected.Subitems[1] := FloatToStrF(selecteditem.Price, ffNumber, 11, 2);
      end
      else begin
        edtItemPrice.Text := CorrectPrice(edtItemPrice.Text);
        edtItemPrice.SelStart := Length(edtItemPrice.Text);
      end;
    end;
  end;
end;

procedure TfrmEditNewItems.chkItemManufactureClick(Sender: TObject);
var
  selecteditem: TNewItem;
begin
  if (ListView.Selected <> nil) then begin
    selecteditem := TNewItem(ListView.Selected.Data);
    if ((selecteditem <> nil) and (selecteditem.CanBeManufactured)) then begin
      selectedItem.Manufacture := chkItemManufacture.Checked;
      case selecteditem.Manufacture of
        false: ListView.Selected.SubItems[2] := 'No';
        true: ListView.Selected.SubItems[2] := 'Yes';
      end;
    end;
  end
end;

procedure TfrmEditNewItems.edtItemBPOMEChange(Sender: TObject);
var
  bpome: Integer;
  selecteditem: TNewItem;
begin
  if (ListView.Selected <> nil) then begin
    selecteditem := TNewItem(ListView.Selected.Data);
    if ((selecteditem <> nil) and (selecteditem.CanBeManufactured)) then begin
      if (TryStrToInt(edtItemBPOME.Text, bpome)) then begin
        selecteditem.BPOME := bpome;
        ListView.Selected.Subitems[3] := IntToStr(selecteditem.BPOME);
      end
    end;
  end;
end;

procedure TfrmEditNewItems.edtNameFilterChange(Sender: TObject);
begin
  filterstring := edtNameFilter.Text;
  LoadItems;
end;

procedure TfrmEditNewItems.btnBuildCostClick(Sender: TObject);
var
  s: String;
begin
  s := StringReplace(btnBuildCost.Caption, global_ds, 'dc', [rfReplaceAll]);
  s := StringReplace(s, global_ts, '', [rfReplaceAll]);
  s := StringReplace(s, global_ds, '', [rfReplaceAll]);
  s := StringReplace(s, 'dc', global_ds, [rfReplaceAll]);
  edtItemPrice.Text := s;
end;

procedure TfrmEditNewItems.ListViewDblClick(Sender: TObject);
begin
  self.btnShowInfoClick(Sender);
end;

procedure TfrmEditNewItems.btnShowInfoClick(Sender: TObject);
var
  frm: TfrmShowInfo;
  item: TNewItem;
begin
  if (ListView.Selected <> nil) then begin
    item := TNewItem(ListView.Selected.Data);
    frm := TfrmShowInfo.Create(self, inventionCalc, item, ACT_None, item.BPOME);
    frm.ShowModal;
    frm.Free;
  end;
end;

procedure TfrmEditNewItems.btnAllItemsBPOMEClick(Sender: TObject);
var
  mestring: String;
  i, me: Integer;
  askagain: Boolean;
begin
  askagain := ListView.Items.Count > 0;
  while (askagain) do begin
    MEstring := '0';
    if (InputQuery('Invention Calculator - Enter BPO ME', 'Enter the BPO ME value for all current items ', mestring)) then begin
      if (TryStrToInt(mestring, me)) then begin
        for i := 0 to ListView.Items.Count -1 do begin
          ListView.Selected := ListView.Items[i];
          edtItemBPOME.Text := IntToStr(me);
        end;
        askagain := false;
      end;
    end
    else askagain := false;
  end;
end;

procedure TfrmEditNewItems.btnEditItemClick(Sender: TObject);
var
  frm: TfrmEditItem;
begin
  if ((ListView.Selected <> nil) and (adminhax)) then begin
    frm := TfrmEditItem.Create(self, TNewItem(ListView.Selected.Data), inventionCalc);
    frm.ShowModal;
    frm.Free;
  end;
end;

procedure TfrmEditNewItems.btnHelpClick(Sender: TObject);
var
  run: TFileRun;
begin
  run := TFileRun.Create(self);
  run.FileName := 'help\EditItems.html';
  run.Execute;
  run.Free;
end;

procedure TfrmEditNewItems.btnNewItemClick(Sender: TObject);
var
  newitem: TNewItem;
  i: Integer;
begin
  if (adminhax) then begin
    if (MessageDlg('Because of the used data structure in this program, any items added can NOT be removed. If you want to remove an item, the only way is to restore a backup of \res\NewItems.dat!' + #10#13#10#13 + 'Are you sure you want to a new item?', mtWarning, [mbYes, mbNo], 0) = mrYes) then begin
      newitem := TNewItem.Create('New item', 1, IT_Unknown);
      i := 0;
      while ((not (inventionCalc.AddItem(newitem))) and (i < inventionCalc.GetNewItemCount)) do begin
        newitem.ID := newitem.ID + 1;
        i := i + 1;
      end;
      LoadItems;
      MessageDlg('Item created with name "New Item"!', mtInformation, [mbOk], 0); 
    end;
  end;
end;

procedure TfrmEditNewItems.ListViewColumnClick(Sender: TObject;
  Column: TListColumn);
begin
  if (inventionCalc.UserSettings.Settings.ItemsSortColumn = Column.Index) then
    inventionCalc.UserSettings.Settings.ItemsSortDirection := (not inventionCalc.UserSettings.Settings.ItemsSortDirection)
  else begin
    inventionCalc.UserSettings.Settings.ItemsSortColumn3 := inventionCalc.UserSettings.Settings.ItemsSortColumn2;
    inventionCalc.UserSettings.Settings.ItemsSortDirection3 := inventionCalc.UserSettings.Settings.ItemsSortDirection2;
    inventionCalc.UserSettings.Settings.ItemsSortColumn2 := inventionCalc.UserSettings.Settings.ItemsSortColumn;
    inventionCalc.UserSettings.Settings.ItemsSortDirection2 := inventionCalc.UserSettings.Settings.ItemsSortDirection;
    inventionCalc.UserSettings.Settings.ItemsSortColumn := Column.Index;
    inventionCalc.UserSettings.Settings.ItemsSortDirection := true;
  end;
  TListView(Sender).AlphaSort;
end;

procedure TfrmEditNewItems.ListViewCompare(Sender: TObject; Item1,
  Item2: TListItem; Data: Integer; var Compare: Integer);
var
  comp: Integer;
  numsort: Boolean;
begin
  numsort := ((ListView.Columns[inventionCalc.UserSettings.Settings.ItemsSortColumn].Caption = 'Price') or
              (ListView.Columns[inventionCalc.UserSettings.Settings.ItemsSortColumn].Caption = 'BPO ME'));
  comp := Sort(Item1, Item2, numsort, inventionCalc.UserSettings.Settings.ItemsSortColumn, inventionCalc.UserSettings.Settings.ItemsSortDirection);
  if (comp = 0) then begin
    numsort := ((ListView.Columns[inventionCalc.UserSettings.Settings.ItemsSortColumn2].Caption = 'Price') or
                (ListView.Columns[inventionCalc.UserSettings.Settings.ItemsSortColumn2].Caption = 'BPO ME'));
    comp := Sort(Item1, Item2, numsort, inventionCalc.UserSettings.Settings.ItemsSortColumn2, inventionCalc.UserSettings.Settings.ItemsSortDirection2);
  end;
  if (comp = 0) then begin
    numsort := ((ListView.Columns[inventionCalc.UserSettings.Settings.ItemsSortColumn3].Caption = 'Price') or
                (ListView.Columns[inventionCalc.UserSettings.Settings.ItemsSortColumn3].Caption = 'BPO ME'));
    comp := Sort(Item1, Item2, numsort, inventionCalc.UserSettings.Settings.ItemsSortColumn3, inventionCalc.UserSettings.Settings.ItemsSortDirection3);
  end;
  Compare := comp;
end;

procedure TfrmEditNewItems.FormClose(Sender: TObject; var Action: TCloseAction);
var
  i: Integer;
begin
  for i := 0 to 11 do begin
    inventionCalc.UserSettings.Settings.ItemsFilter[i] := filter[i];
  end;
end;

procedure TfrmEditNewItems.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
  i: Integer;
begin
  for i := 0 to 11 do begin
    inventionCalc.UserSettings.Settings.ItemsFilter[i] := filter[i];
  end;
  CanClose := true;
end;

procedure TfrmEditNewItems.UpdateTypeFilter(itemtype: EItemType; checked: Boolean);
begin
  filter[EItemTypeToInteger(itemtype)] := checked;
  LoadItems;
end;

procedure TfrmEditNewItems.chkT1ItemClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_T1Item, chkT1Item.Checked);
end;

procedure TfrmEditNewItems.chkT2ItemClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_T2Item, chkT2Item.Checked);
end;

procedure TfrmEditNewItems.chkAdvancedMaterialClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_AdvancedMaterial, chkAdvancedMaterial.Checked);
end;

procedure TfrmEditNewItems.chkComponentClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_T2Component, chkComponent.Checked);
end;

procedure TfrmEditNewItems.chkRAMClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_RAM, chkRAM.Checked);
end;

procedure TfrmEditNewItems.chkTradegoodsClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_Tradegoods, chkTradegoods.Checked);
end;

procedure TfrmEditNewItems.chkDatacoreClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_Datacore, chkDatacore.Checked);
end;

procedure TfrmEditNewItems.chkMineralClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_Mineral, chkMineral.Checked);
end;

procedure TfrmEditNewItems.chkCapComponentClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_CapComponent, chkCapComponent.Checked);
end;

procedure TfrmEditNewItems.chkCapT2ComponentClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_CapT2Component, chkCapT2Component.Checked);
end;

procedure TfrmEditNewItems.chkSalvageClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_Salvage, chkSalvage.Checked);
end;

procedure TfrmEditNewItems.chkInterfaceClick(Sender: TObject);
begin
  UpdateTypeFilter(IT_DataInterface, chkInterface.Checked);
end;

procedure TfrmEditNewItems.ListViewCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
var
  newitem: TNewItem;
begin
  if (inventioncalc.UserSettings.Colors.ColorEditItems) then begin
    newitem := TNewItem(Item.Data);
    if (newitem <> nil) then begin
      ListView.Canvas.Font.Color := inventionCalc.UserSettings.Colors.GetColor(newitem.ItemType);
    end
    else ListView.Canvas.Font.Color := clDefault;
  end;
end;

procedure TfrmEditNewItems.btnAllItemsBuildCostClick(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to ListView.Items.Count -1 do begin
    ListView.Selected := ListView.Items[i];
    btnBuildCostClick(btnAllItemsBuildCost);
  end;
end;

procedure TfrmEditNewItems.btnAllItemsManufactureClick(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to ListView.Items.Count -1 do begin
    ListView.Selected := ListView.Items[i];
    chkItemManufacture.Checked := manufacture;
  end;
  manufacture := not manufacture;
end;

procedure TfrmEditNewItems.btnDecryptorsClick(Sender: TObject);
var
  gui: TfrmDecryptors;
begin
  gui := TfrmDecryptors.Create(self, inventionCalc);
  gui.ShowModal;
  gui.Destroy;
end;

procedure TfrmEditNewItems.btnImportPricesClick(Sender: TObject);
var
  i, len: Integer;
  gui: TfrmImportPrices;
  itemslist: TNewItemsList;
  containsinterface: Boolean;
begin
  SetLength(itemslist, 0);
  containsinterface := false;
  for i := 0 to ListView.Items.Count -1 do begin
    len := Length(itemslist);
    SetLength(itemslist, len +1);
    itemslist[len] := TNewItem(ListView.Items[i].Data);
    if (TNewItem(ListView.Items[i].Data).ItemType = IT_DataInterface) then containsinterface := true;
  end;
  if (containsinterface) then begin
    if (MessageDlg('It is not recommended to change the price of a data interface, as this will severely reduce the accuracy of this program!'#10#13#10#13'Are you sure you want to continue with importing prices?', mtWarning, [mbOk, mbCancel], 0) = mrCancel) then begin
      exit;
    end;  
  end;
  gui := TfrmImportPrices.Create(self, itemslist, inventioncalc);
  if (gui.ShowModal <> mrCancel) then LoadItems;
  gui.Destroy;
end;

procedure TfrmEditNewItems.edtItemPriceEnter(Sender: TObject);
var
  item: TNewItem;
begin
  if (ListView.Selected <> nil) then begin
    item := TNewItem(ListView.Selected.Data);
    if ((item.ItemType = IT_DataInterface) and (item.Price = 0)) then begin
      MessageDlg('It is not recommended to change the price of a data interface, as this will severely reduce the accuracy of this program!', mtWarning, [mbOk], 0);
    end;
  end;
end;

end.
